﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;

namespace LightWeb.BlogCore
{
    public class Blog
    {
        /// <summary>
        ///     The virtual path to the blog instance
        /// </summary>
        private string virtualPath;

        /// <summary>
        ///     The relative web root.
        /// </summary>
        private string relativeWebRoot;

        /// <summary>
        /// The sync root.
        /// </summary>
        /// 
        private static readonly object SyncRoot = new object();

        private static Blog _instance = null;
        /// <summary>
        /// The current blog instance.
        /// </summary>
        public static Blog CurrentInstance
        {
            get
            {
                if (_instance == null)
                    _instance = new Blog();
                return _instance;
            }
        }

        /// <summary>
        ///     Gets or sets the virtual path to the blog instance.
        /// </summary>
        public string VirtualPath
        {
            get
            {
                return this.virtualPath;
            }

            set
            {
                // RelativeWebRoot is based on VirtualPath.  Clear relativeWebRoot
                // so RelativeWebRoot is re-generated.
                this.relativeWebRoot = null;
                this.virtualPath = value;
                //base.SetValue("VirtualPath", value, ref this.virtualPath);
            }
        }

        /// <summary>
        ///     Gets the optional hostname of the blog instance.
        /// </summary>
        public string Hostname
        {
            get;
            set;
        }
        /// <summary>
        ///     Gets a mappable virtual path to the blog instance's storage folder.
        /// </summary>
        public string StorageLocation
        {
            get
            {
                // only the Primary blog instance should have an empty StorageContainerName
                if (string.IsNullOrWhiteSpace(this.StorageContainerName))
                {
                    return BlogConfig.StorageLocation;
                }

                return string.Format("{0}{1}/{2}/", BlogConfig.StorageLocation, BlogConfig.BlogInstancesFolderName, this.StorageContainerName);
            }
        }
        /// <summary>
        ///     Gets or sets the storage container name.
        /// </summary>
        public string StorageContainerName
        { get; set; }
        public Guid Id { get; set; }

        /// <summary>
        ///     Gets the relative root of the blog instance.
        /// </summary>
        /// <value>A string that ends with a '/'.</value>
        public string RelativeWebRoot
        {
            get
            {
                return relativeWebRoot ??
                   (relativeWebRoot =
                    VirtualPathUtility.ToAbsolute(VirtualPathUtility.AppendTrailingSlash(this.VirtualPath ?? BlogConfig.VirtualPath)));
            }
        }

        /// <summary>
        ///     Gets the absolute root of the blog instance.
        /// </summary>
        public Uri AbsoluteWebRoot
        {
            get
            {
                string contextItemKey = string.Format("{0}-absolutewebroot", this.Id);

                var context = HttpContext.Current;
                if (context == null)
                {
                    throw new WebException("The current HttpContext is null");
                }

                Uri absoluteWebRoot = context.Items[contextItemKey] as Uri;
                if (absoluteWebRoot != null) { return absoluteWebRoot; }

                UriBuilder uri = new UriBuilder();
                if (!string.IsNullOrWhiteSpace(this.Hostname))
                    uri.Host = this.Hostname;
                else
                {
                    uri.Host = context.Request.Url.Host;
                    if (!context.Request.Url.IsDefaultPort)
                    {
                        uri.Port = context.Request.Url.Port;
                    }
                }

                string vPath = this.VirtualPath ?? string.Empty;
                if (vPath.StartsWith("~/")) { vPath = vPath.Substring(2); }
                uri.Path = string.Format("{0}{1}", Utils.ApplicationRelativeWebRoot, vPath);
                if (!uri.Path.EndsWith("/")) { uri.Path += "/"; }

                absoluteWebRoot = uri.Uri;
                context.Items[contextItemKey] = absoluteWebRoot;

                return absoluteWebRoot;
            }
        }
    }
}
